import os.path

from twisted.web import resource,server,static

import feedparser

from util import html

class WebError(Exception):
    pass

class SessionState(object):
    pass

class WebQuery(resource.Resource):
    """
    Implements a web resource that handles GET and POST requests.
    
    Requests are matched to a per-service and per-client-window session
    state object. The client must include a 'uid' parameter in the
    request to support the per-client-window session state mapping.
    """
    isLeaf = True
    title = 'uci@home'

    services = [ ]
    
    def __init__(self,serviceName):
        if serviceName in self.services:
            raise WebError('Service already registered: %s' % serviceName)
        self.serviceName = serviceName
        WebQuery.services.append(serviceName)

    def get_arg(self,name,default=None):
        try:
            return self.args[name][0]
        except (AttributeError,KeyError):
            return default

    def prepare(self,request):
        self.args = request.args
        request.sitepath = [self.serviceName]
        session = request.getSession()
        if not 'uid' in request.args:
            uid = 0
        else:
            uid = request.args['uid'][0]
        #print 'Retrieving session state for uid',uid,'in',id(session)
        if not hasattr(session,'state'):
            session.state = { }
        if not uid in session.state:
            session.state[uid] = SessionState()
        return (session,session.state[uid])

    def render_GET(self, request):
        (session,state) = self.prepare(request)
        doc = html.HTMLDocument(
            html.Head(title=self.title,css='/static/styles.css',icon='/static/favicon.ico'),
            html.Body(
                html.Div('uci@home',html.Span(id='menu'),id='header'),
                html.Div(id='content')
            )
        )
        doc.head.js = ['static/jquery-1.3.2.min.js','static/jquery.flot.pack.js']
        # IE does not yet support the canvas tag that flot needs so the
        # following HTML hack only loads the excanvas library on IE
        doc.head.raw = [
            '<!--[if IE]><script language="javascript" type="text/javascript" ' +
            'src="static/excanvas.pack.js"></script><![endif]-->'
        ]
        for separator,service in enumerate(WebQuery.services):
            if separator:
                doc['menu'].append(' | ')
            if service == self.serviceName:
                doc['menu'].append(service)
            else:
                doc['menu'].append(html.A(service,href='/%s' % service))
        self.GET(request,session,state,doc['content'])
        return str(doc)

    def render_POST(self, request):
        (session,state) = self.prepare(request)
        return self.POST(request,session,state)

class LocalHandler(WebQuery):

    title = 'local@home'

    def __init__(self,serviceName,settings):
        self.settings = settings
        self.feedAddr = ('http://feeds.weatherbug.com/rss.aspx?zipcode=%s&feed=currtxt' %
            (settings.get('local','zip')))
        WebQuery.__init__(self,serviceName)

    def GET(self,request,session,state,content):
        content.append(html.H1('Weather'))
        weather = feedparser.parse(self.feedAddr)
        content.extend([
            html.Text(weather.entries[0].title,escapeMe=False),
            html.Br(),html.Br(),
            html.Text(weather.entries[0].summary,escapeMe=False)])
        content.append(html.H1('Sunshine'))
        content.append(html.H1('Utilities'))

    def POST(self,request,session,state):
        pass

class CommunityHandler(WebQuery):

    title = 'community@home'

    def __init__(self,serviceName):
        WebQuery.__init__(self,serviceName)

    def GET(self,request,session,state,content):
        content.append(html.H1('Neighborhood'))
        content.append(html.H1('Region'))
        content.append(html.H1('Discussions'))

    def POST(self,request,session,state):
        pass

class SettingsHandler(WebQuery):

    title = 'settings@home'

    def __init__(self,serviceName,settings):
        self.settings = settings
        WebQuery.__init__(self,serviceName)

    def GET(self,request,session,state,content):
        content.append(html.H1('Preferences'))
        content.append(html.Div('Temperatures reported in ',
            html.Entity('deg'),self.settings.get('prefs','tempunits')))
        content.append(html.H1('Location'))
        content.append(html.Div('USA ZIP code ',self.settings.getint('local','zip')))
        content.append(html.Div('Electric power costs $%.2f per kilowatt-hour' %
            self.settings.getfloat('local','electricityrate')))
        content.append(html.H1('Modules'))
        content.append(html.Div('1 prototype'))

    def POST(self,request,session,state):
        pass

class Site(server.Site):
    
    def __init__(self,logger,settings,path):
        from hub import home,debug
        # create an empty root for our site
        root = resource.Resource()
        # serve our static content
        root.putChild('static',static.File(os.path.join(path,'web')))
        # serve our dynamic content
        root.putChild('home',home.HomeHandler('home',logger,settings))
        root.putChild('local',LocalHandler('local',settings))
        root.putChild('community',CommunityHandler('community'))
        root.putChild('settings',SettingsHandler('settings',settings))
        root.putChild('debug',debug.DebugHandler('debug',logger,settings))
        server.Site.__init__(self,root)